/**
 * LGPL
 * @Author jw12
 */
package org.biodas.jdas.client;

/**
 * 
 * LPGL
 *@author JWarren
 *
 */
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

import javax.xml.bind.JAXBContext;

import javax.xml.bind.JAXBException;

import javax.xml.bind.Unmarshaller;

import javax.xml.bind.Marshaller;

import javax.xml.parsers.ParserConfigurationException;

import javax.xml.parsers.SAXParser;

import javax.xml.parsers.SAXParserFactory;

import javax.xml.transform.sax.SAXSource;

import org.xml.sax.InputSource;

import org.xml.sax.SAXException;

import org.xml.sax.XMLReader;

public class NoDtdJaxbParser {

	private static final String EXTERNAL_DTD_LOADING_FEATURE =

	"http://apache.org/xml/features/nonvalidating/load-external-dtd";

	private SAXParserFactory mParserFactory = null;

	private XMLReader mParser = null;

	public NoDtdJaxbParser() {

		mParserFactory = SAXParserFactory.newInstance();

		mParserFactory.setNamespaceAware(true);

		mParserFactory.setValidating(false);

	}

	public Object parseXmlFile(File aXmlFile, String aPackage)
			throws JAXBException {

		XMLReader lReader = null;

		try {

			lReader = getXmlReader();

		} catch (Exception e) {

			JAXBException lEx = new JAXBException("Error creating SAX Parser");

			lEx.setLinkedException(e);

			throw lEx;

		}

		JAXBContext lContext = JAXBContext.newInstance(aPackage);

		Unmarshaller lUnmarshaller = lContext.createUnmarshaller();

		FileInputStream lXmlStream = null;

		try {

			try {
				lXmlStream = new FileInputStream(aXmlFile);
			} catch (FileNotFoundException e) {
				
				e.printStackTrace();
			}

			SAXSource lSource = new SAXSource(lReader, new InputSource(
					lXmlStream));

			return lUnmarshaller.unmarshal(lSource);

		} finally {

			if (lXmlStream != null) {

				try {

					lXmlStream.close();

				} catch (Exception e) {

					// ignore

				}

			}

		}

	}


   public Object parseXmlUrl(String urlString, String aPackage)
     throws JAXBException, IOException
   {
     return parseXmlUrl(urlString, aPackage, null);
   }
 
   public Object parseXmlUrl(String urlString, String aPackage, ConnectionPropertyProviderI connProps)
     throws JAXBException, IOException
   {
     XMLReader lReader = null;
     try
     {
       lReader = getXmlReader();
     }
     catch (Exception e)
     {
       JAXBException lEx = new JAXBException("Error creating SAX Parser");
 
       lEx.setLinkedException(e);
 
       throw lEx;
     }
 
     JAXBContext lContext = JAXBContext.newInstance(aPackage);
 
     Unmarshaller lUnmarshaller = lContext.createUnmarshaller();
     URL url = null;
     try {
       url = new URL(urlString);
     }
     catch (MalformedURLException e) {
       e.printStackTrace();
     }
     boolean retry = true;
     while (retry)
     {
       URLConnection uc = null;
       try {
         uc = url.openConnection();
         if ((connProps != null) && ((uc instanceof HttpURLConnection)))
         {
           connProps.setConnectionProperties((HttpURLConnection)uc);
         }
       }
       catch (IOException e) {
         e.printStackTrace();
       }
       InputStreamReader input = null;
       SAXSource lSource = null;
       try {
         
           input = new InputStreamReader(uc.getInputStream());
           lSource = new SAXSource(lReader, new InputSource(input));
         
         if ((connProps != null) && ((uc instanceof HttpURLConnection)))
           retry = connProps
             .getResponseProperties((HttpURLConnection)uc);
         else {
           retry = false;
         }
         if (!retry)
           return lUnmarshaller.unmarshal(lSource);
       }
       finally {
         try {
           if (input != null)
             input.close();
         }
         catch (IOException e) {
           e.printStackTrace();
         }
       }
     }
     return null;
   }
 

	private synchronized XMLReader getXmlReader()
			throws ParserConfigurationException, SAXException {

		if (mParser == null) {

			SAXParser lSaxParser = mParserFactory.newSAXParser();

			XMLReader lReader = lSaxParser.getXMLReader();

			// Implementation note: The following method call will raise an
			// exception if

			// xerxes is not the SAX Parser. You may choose instead to catch the
			// raised

			// exception and ignore it.

			lReader.setFeature(EXTERNAL_DTD_LOADING_FEATURE, false);

			mParser = lReader;

		}

		return mParser;

	}

}